package com.fanketly.module_safe_photo

import ando.file.core.FileLogger
import ando.file.core.FileUri
import ando.file.selector.FileSelectCallBack
import ando.file.selector.FileSelectResult
import ando.file.selector.FileSelector
import android.content.Intent
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.EditOff
import androidx.compose.runtime.*
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import coil.compose.AsyncImage
import com.alibaba.android.arouter.facade.annotation.Route
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.fanketly.core_lib_bean.POSITION_INCREMENT
import com.fanketly.core_lib_bean.REQUEST_CHOOSE_FILE
import com.fanketly.core_lib_compose_ui.MyBackTopAppBar
import com.fanketly.core_lib_compose_ui.TextFiledDialogModelState
import com.fanketly.core_lib_compose_ui.TipDialogModelState
import com.fanketly.core_lib_compose_ui.theme.UtilsAppTheme
import com.fanketly.module_safe_photo.data.DialogState
import com.fanketly.module_safe_photo.data.model.BasePhotoModel
import com.fanketly.module_safe_photo.data.model.SafePhotoModel
import com.fanketly.module_safe_photo.data.model.SafePhotoSortModel
import com.fanketly.module_safe_photo.domain.SafePhotoEvent
import com.fanketly.module_safe_photo.domain.SafePhotoRequester
import com.fanketly.module_safe_photo.ui.VerticalReorderGrid
import com.hjq.permissions.Permission
import fanketly.core.lib.base.ui.BaseComposeMVIActivity
import fanketly.core.lib.base.utils.PermissionsUtils
import fanketly.core.lib.router.module.safe_photo.SafePhotoRouter
import fanketly.core.utils.selectPhoto
import kotlinx.coroutines.launch
import org.burnoutcrew.reorderable.ItemPosition

@Route(path = SafePhotoRouter.PATH_MAIN, group = SafePhotoRouter.GROUP)
class SafePhotoActivity : BaseComposeMVIActivity<SafePhotoRequester>() {
    private lateinit var mSelectPhoto: FileSelector
    private val mStartForResult: ActivityResultLauncher<Intent> =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            FileLogger.w("Back ok -> ActivityResultCallback")
            mSelectPhoto.obtainResult(REQUEST_CHOOSE_FILE, result.resultCode, result.data)
        }

    /**
     * 需要保存状态时新建ViewModel保存
     * */
    private lateinit var mData: MutableState<List<SafePhotoModel>>
    private lateinit var mSortData: SnapshotStateList<SafePhotoSortModel>
    private lateinit var mEditState: MutableState<Boolean>
    private var mPhotoScreen by mutableStateOf<SafePhotoSortModel?>(null)//null 为在Sort界面，notnull 在SortDetail
    private val openTextFiledDialog: MutableState<DialogState?> by lazy { mutableStateOf(null) }
    private val openTipDialog: MutableState<BasePhotoModel?> by lazy { mutableStateOf(null) }

    override fun initView() {
//        if (FingerprintUtils.supportFingerprint(this)) {
//            FingerprintUtils.showBiometricPrompt(this) {
        mData = mutableStateOf(emptyList())
        mSortData = mutableStateListOf()
        PermissionsUtils.openPermissions(this, Permission.READ_MEDIA_IMAGES) { _, _ ->
            viewModel.input(SafePhotoEvent.GetPhotoSortList())
        }
        mEditState = mutableStateOf(false)
        setContent {
            UtilsAppTheme {
                if (mPhotoScreen == null) {
                    PhotoSort(mSortData)
                } else {
                    PhotoSortDetail(mPhotoScreen!!)
                }
                /*Dialog*/
                TipDialogModelState(tipContent = "是否删除该图片", openTipDialog) {
                    viewModel.input(SafePhotoEvent.DeletePhoto(it))
                }
                TextFiledDialogModelState("分类", openTextFiledDialog) {
                    if (it.isEmpty()) return@TextFiledDialogModelState
                    openTextFiledDialog.value!!.let { value ->
                        if (value is DialogState.OpenEdit) {
                            value.model.sortName = it
                            value.model.let { a ->
                                mSortData[value.index] = SafePhotoSortModel(
                                    a.sortName,
                                    a.path,
                                    a.position,
                                    a.sortPosition
                                )
                            }
                            viewModel.input(
                                SafePhotoEvent.EditPhotoSort(value.model)
                            )

                        } else if (value is DialogState.Open) mSortData.let { a ->
                            if (a.isEmpty()) {
                                viewModel.input(
                                    SafePhotoEvent.AddPhotoSort(
                                        SafePhotoSortModel(
                                            it, null, POSITION_INCREMENT, 0
                                        )
                                    )
                                )
                            } else {
                                LogUtils.d(a.maxBy { b -> b.sortPosition }.sortPosition + 1)
                                viewModel.input(
                                    SafePhotoEvent.AddPhotoSort(
                                        SafePhotoSortModel(
                                            it, null,
                                            mSortData.last().position + POSITION_INCREMENT,
                                            a.maxBy { b -> b.sortPosition }.sortPosition + 1
                                        )
                                    )
                                )
                            }
                        }
                    }
                }
            }
        }
//            }
//        }
    }

    override fun initData() {
    }

    override fun onInput() {
    }

    /**
     * 存在一个选择，选择抽象但是耦合还是选择解耦但是代码多
     * */
    override fun onOutput() {
        viewModel.output(this) {
            when (it) {
                is SafePhotoEvent.AddPhotoSort -> {
                    mSortData.add(it.any!!)
                }
                is SafePhotoEvent.DeletePhotoSort -> if (!it.isSuccess) {
                    ToastUtils.showShort("删除失败")
                }
                is SafePhotoEvent.EditPhotoSort -> if (!it.isSuccess) {
                    ToastUtils.showShort("编辑失败")
                } else {
                    LogUtils.d(it.model)
//                    mSortData.value = mSortData.value.toList()
//                    mSortData.value = mSortData.value
//                        .apply {
//                        find { a -> a.id == it.model!!.id }!!.sortName = it.model!!.sortName
//                    }

                }

                is SafePhotoEvent.GetPhotoSortList -> {
                    mSortData.addAll(it.list!!)
                }
                /**/
                is SafePhotoEvent.GetPhotoList -> {
                    mData.value = it.list!!
                    LogUtils.d(mData.value.size)
                }
                is SafePhotoEvent.SwitchPhoto -> if (!it.isSuccess) {
                    ToastUtils.showShort("交换失败")
                }
                is SafePhotoEvent.DeletePhoto -> if (!it.isSuccess) {
                    ToastUtils.showShort("删除失败")
                } else {
                    if (it.basePhotoModel is SafePhotoModel) {
                        mData.value =
                            mData.value.toMutableList().apply { remove(it.basePhotoModel) }
                    } else {
                        mSortData.remove(it.basePhotoModel)
                    }
                }
                is SafePhotoEvent.AddPhoto -> {
                    mData.value = mData.value.toMutableList().apply {
                        add(it.any!!)
                    }
                }
            }
        }
    }


    override fun onDestroy() {
        mStartForResult.unregister()
        super.onDestroy()
    }

    @Composable
    fun PhotoSort(list: SnapshotStateList<SafePhotoSortModel>) {
        val scaffoldState = rememberScaffoldState()
//                val scope = rememberCoroutineScope()
        Scaffold(
            modifier = Modifier,
            scaffoldState = scaffoldState,
            topBar = {
                MyBackTopAppBar(text = stringResource(id = R.string.core_ui_safe_photo), actions = {
                    IconButton(
                        content = {
                            Icon(
                                if (mEditState.value) Icons.Default.Edit
                                else Icons.Default.EditOff,
                                tint = Color.White,
                                contentDescription = "edit"
                            )
                        },
                        onClick = {
                            mEditState.value = mEditState.value.not()
                        }
                    )
                }, onClick = { finish() })
            },
            floatingActionButton = {
                IconButton(
                    modifier = Modifier.size(48.dp),
                    onClick = {
                        openTextFiledDialog.value = DialogState.Open
                    }) {
                    Icon(
                        painter = painterResource(id = R.drawable.ic_baseline_add_circle_38),
                        modifier = Modifier.size(48.dp),
                        contentDescription = "add"
                    )
                }
            },
            floatingActionButtonPosition = FabPosition.End,
            content = {
                VerticalReorderGrid(3, list, onMove = { from, to ->
                    //移动之前的位置
                    switchPhoto2(list, from, to)
                }, gridModifier = Modifier.padding(it), onDoubleClick = { model, index ->
                    if (mEditState.value) {
                        LogUtils.d(model)
                        openTextFiledDialog.value = DialogState.OpenEdit(model, index)
                    } else {
                        openTipDialog.value = model
                    }
                }) { model, _ ->
                    mPhotoScreen = model
                }
            }
        )
    }

    @Composable
    fun PhotoSortDetail(model: SafePhotoSortModel) {
        viewModel.input(SafePhotoEvent.GetPhotoList(model.sortPosition))
        var showFullPhoto by remember { mutableStateOf<String?>(null) }
        val scaffoldState = rememberScaffoldState()
//                val scope = rememberCoroutineScope()
        Scaffold(
            modifier = Modifier,
            scaffoldState = scaffoldState,
            topBar = {
                MyBackTopAppBar(text = model.sortName) {
                    mPhotoScreen = null
                    mData.value = emptyList()
                }
            },
            floatingActionButton = {
                IconButton(
                    modifier = Modifier.size(48.dp),
                    onClick = {
                        mSelectPhoto = selectPhoto(this, mStartForResult,
                            object : FileSelectCallBack {
                                override fun onSuccess(results: List<FileSelectResult>?) {
                                    LogUtils.d(results?.size)
//                                    results?.forEach {
                                    results?.get(0)?.uri?.let { path ->
                                        val position =
                                            if (mData.value.isEmpty()) POSITION_INCREMENT
                                            else mData.value.last().position + POSITION_INCREMENT
                                        LogUtils.d("POSITION_INCREMENT:$POSITION_INCREMENT")
                                        val safePhotoModel = SafePhotoModel(
                                            FileUri.getPathByUri(path) ?: "",
                                            position,
                                            model.sortPosition
                                        )
                                        lifecycleScope.launch {
                                            viewModel.input(
                                                SafePhotoEvent.AddPhoto(
                                                    safePhotoModel
                                                )
                                            )
                                        }
                                    }
//                                    }
                                }

                                override fun onError(e: Throwable?) {
                                    FileLogger.e("FileSelectCallBack onError ${e?.message}")
                                }
                            }
                        )
                    }) {
                    Icon(
                        painter = painterResource(id = R.drawable.ic_baseline_add_circle_38),
                        modifier = Modifier.size(48.dp),
                        contentDescription = "add"
                    )
                }
            },
            floatingActionButtonPosition = FabPosition.End,
            content = {
                if (mData.value.isNotEmpty()) VerticalReorderGrid(
                    4,
                    mData.value,
                    onMove = { from, to ->
                        //移动之前的位置
                        switchPhoto(mData, from, to)
                    },
                    Modifier.padding(it),
                    onDoubleClick = { model, _ ->
                        openTipDialog.value = model
                    },
                    onClick = { model, index ->
                        showFullPhoto = model.path
                    })
            }
        )
        if (showFullPhoto != null) {
            AsyncImage(
                model = showFullPhoto,
                contentDescription = null,
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.White)
                    .clickable {
                        showFullPhoto = null
                    }
            )
        }
    }

    private fun <E : BasePhotoModel> switchPhoto2(
        list: SnapshotStateList<E>,
        from: ItemPosition,
        to: ItemPosition
    ) {
        //移动之前的位置
        list.apply {
            val targetPosition = to.index
            val sourcePosition = from.index
            val sourceModel = this[sourcePosition]
            val targetModel = this[targetPosition]
            LogUtils.d(targetPosition, sourcePosition)
            when (targetPosition) {
                0 -> {
                    sourceModel.position = targetModel.position / 2
                }
                size - 1 -> {
                    sourceModel.position =
                        targetModel.position + POSITION_INCREMENT
                }
                else -> {
                    if (targetPosition > sourcePosition) {
                        sourceModel.position =
                            (this[targetPosition + 1].position + targetModel.position) / 2
                    } else {
                        sourceModel.position =
                            (this[targetPosition - 1].position + targetModel.position) / 2
                    }

//                                    val position =
//                                        if (sourcePosition + 1 != targetPosition) sourcePosition + 1
//                                        else sourcePosition - 1
//                                    val model = this[position]
//                                    sourceModel.position =
//                                        (model.position + targetModel.position) / 2
                }
            }
//{ from, to ->
//                data.value = data.value.toMutableList().apply {
//                    add(to.index, removeAt(from.index))
//                }
//            }
            add(targetPosition, removeAt(sourcePosition))
            viewModel.input(SafePhotoEvent.SwitchPhoto(sourceModel))

        }
    }

    private fun <E : BasePhotoModel> switchPhoto(
        data: MutableState<List<E>>,
        from: ItemPosition,
        to: ItemPosition
    ) {
        //移动之前的位置
        data.value = data.value.toMutableList().apply {
            val targetPosition = to.index
            val sourcePosition = from.index
            val sourceModel = this[sourcePosition]
            val targetModel = this[targetPosition]
            LogUtils.d(targetPosition, sourcePosition)
            when (targetPosition) {
                0 -> {
                    sourceModel.position = targetModel.position / 2
                }
                size - 1 -> {
                    sourceModel.position =
                        targetModel.position + POSITION_INCREMENT
                }
                else -> {
                    if (targetPosition > sourcePosition) {
                        sourceModel.position =
                            (this[targetPosition + 1].position + targetModel.position) / 2
                    } else {
                        sourceModel.position =
                            (this[targetPosition - 1].position + targetModel.position) / 2
                    }

//                                    val position =
//                                        if (sourcePosition + 1 != targetPosition) sourcePosition + 1
//                                        else sourcePosition - 1
//                                    val model = this[position]
//                                    sourceModel.position =
//                                        (model.position + targetModel.position) / 2
                }
            }
//{ from, to ->
//                data.value = data.value.toMutableList().apply {
//                    add(to.index, removeAt(from.index))
//                }
//            }
            add(targetPosition, removeAt(sourcePosition))
            viewModel.input(SafePhotoEvent.SwitchPhoto(sourceModel))

        }
    }
}



